/******************************************************************************
*	usbd/descriptors.h
*	 by Alex Chadwick
*
*	A light weight implementation of the USB protocol stack fit for a simple
*	driver.
*
*	usbd/descriptors.h contains structures defined in the USB standard that
*	describe various aspects of USB.
******************************************************************************/
#ifndef _USBD_DESCRIPTORS_H
#define _USBD_DESCRIPTORS_H

#include <types.h>

//------------------------------------------------------------------------------
// USB descriptor header has a 'type'
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 9.6
//
typedef
	enum DescriptorTYPE {
		Device                  =  1,
		Configuration           =  2,
		String                  =  3,
		Interface               =  4,
		Endpoint                =  5,
		DeviceQualifier         =  6,
		OtherSpeedConfiguration =  7,
		InterfacePower          =  8,
		Hid                     = 33,
		HidReport               = 34,
		HidPhysical             = 35,
		Hub                     = 41,
	}
DescriptorTYPE;

//------------------------------------------------------------------------------
// USB descriptor header
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 9.6
//
typedef
	struct UsbDescriptorHeader {
		u8              DescriptorLength;   // +0x0
		DescriptorTYPE  DescriptorType : 8; // +0x1
	}
UsbDescriptorHeader;

//------------------------------------------------------------------------------
// USB device: Descriptor
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 9.6.1
//
typedef
	enum DeviceClass {
		DeviceClassInInterface    = 0x00,
		DeviceClassCommunications = 0x02,
		DeviceClassHub            = 0x09,
		DeviceClassDiagnostic     = 0xDC,
		DeviceClassMiscellaneous  = 0xEF,
		DeviceClassVendorSpecific = 0xFF,
	}
DeviceClass;

typedef
	struct UsbDeviceDescriptor {
		u8             DescriptorLength;    // +0x00
		DescriptorTYPE DescriptorType : 8;  // +0x01
		u16            UsbVersion;          // +0x02 (BCD Eg. 0x210 => v2.10)
		DeviceClass    Class : 8;           // +0x4
		u8             SubClass;            // +0x5
		u8             Protocol;            // +0x6
		u8             MaxPacketSize0;      // +0x7
		u16            VendorId;            // +0x8
		u16            ProductId;           // +0xa
		u16            Version;             // +0xc
		u8             Manufacturer;        // +0xe
		u8             Product;             // +0xf
		u8             SerialNumber;        // +0x10
		u8             ConfigurationCount;  // +0x11
	} STRUCTPACK
UsbDeviceDescriptor;

//------------------------------------------------------------------------------
// USB device: Qualifier descriptor
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 9.6.2
//
typedef
	struct UsbDeviceQualifierDescriptor {
		u8 DescriptorLength;                // +0x0
		DescriptorTYPE DescriptorType : 8;  // +0x1
		u16 UsbVersion;                     // +0x02 (BCD Eg. 0x210 => v2.10)
		DeviceClass Class : 8;              // +0x4
		u8 SubClass;                        // +0x5
		u8 Protocol;                        // +0x6
		u8 MaxPacketSize0;                  // +0x7
		u8 ConfigurationCount;              // +0x8
		u8 _reserved9;                      // +0x9
	} STRUCTPACK
UsbDeviceQualifierDescriptor;

//------------------------------------------------------------------------------
// USB device: Configuration descriptor
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 9.6.3
//
typedef
		struct UcdAttribs {
			unsigned _reserved0_4 : 5;  // @0
			bool RemoteWakeup     : 1;  // @5
			bool SelfPowered      : 1;  // @6
			unsigned _reserved7   : 1;  // @7
		}
UcdAttribs;

typedef
	struct UsbConfigurationDescriptor {
		u8             DescriptorLength;    // +0x0
		DescriptorTYPE DescriptorType : 8;  // +0x1
		u16            TotalLength;         // +0x2
		u8             InterfaceCount;      // +0x4
		u8             ConfigurationValue;  // +0x5
		u8             StringIndex;         // +0x6
		UcdAttribs     Attributes;          // +0x7
		u8             MaximumPower;        // +0x8
	} STRUCTPACK
UsbConfigurationDescriptor;

//------------------------------------------------------------------------------
// USB device: Other speed configuration descriptor
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 9.6.4
//
typedef
	enum UoscdAttribs_reserved7 {
		Valid = 1,
	}
UoscdAttribs_reserved7;

typedef
	struct UoscdAttribs {
		unsigned               _reserved0_4 : 5;  // @0
		bool                   RemoteWakeup : 1;  // @5
		bool                   SelfPowered  : 1;  // @6
		UoscdAttribs_reserved7 _reserved7   : 1;  // @7
	}
UoscdAttribs;

typedef
	struct UsbOtherSpeedConfigurationDescriptor {
		u8             DescriptorLength;      // +0x0
		DescriptorTYPE DescriptorType : 8;    // +0x1
		u16            TotalLength;           // +0x2
		u8             InterfaceCount;        // +0x4
		u8             ConfigurationValue;    // +0x5
		u8             StringIndex;           // +0x6
		UoscdAttribs   Attributes;            // +0x7
		u8             MaximumPower;          // +0x8
	} STRUCTPACK
UsbOtherSpeedConfigurationDescriptor;

//------------------------------------------------------------------------------
// USB device: Interface descriptor
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 9.6.5
//
typedef
	enum InterfaceClass {
		InterfaceClassReserved            = 0x00,
		InterfaceClassAudio               = 0x01,
		InterfaceClassCommunications      = 0x02,
		InterfaceClassHid                 = 0x03,
		InterfaceClassPhysical            = 0x05,
		InterfaceClassImage               = 0x06,
		InterfaceClassPrinter             = 0x07,
		InterfaceClassMassStorage         = 0x08,
		InterfaceClassHub                 = 0x09,
		InterfaceClassCdcData             = 0x0A,
		InterfaceClassSmartCard           = 0x0B,
		InterfaceClassContentSecurity     = 0x0D,
		InterfaceClassVideo               = 0x0E,
		InterfaceClassPersonalHealthcare  = 0x0F,
		InterfaceClassAudioVideo          = 0x10,
		InterfaceClassDiagnosticDevice    = 0xDC,
		InterfaceClassWirelessController  = 0xE0,
		InterfaceClassMiscellaneous       = 0xEF,
		InterfaceClassApplicationSpecific = 0xFE,
		InterfaceClassVendorSpecific      = 0xFF,
	}
InterfaceClass;

typedef
	struct UsbInterfaceDescriptor {
		u8             DescriptorLength;    // +0x0
		DescriptorTYPE DescriptorType : 8;  // +0x1
		u8             Number;              // +0x2
		u8             AlternateSetting;    // +0x3
		u8             EndpointCount;       // +0x4
		InterfaceClass Class : 8;           // +x05
		u8             SubClass;
		u8             Protocol;
		u8             StringIndex;
	} STRUCTPACK
UsbInterfaceDescriptor;

//------------------------------------------------------------------------------
// USB device: Endpoint descriptor
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 9.6.6
//
typedef
	struct UedEndpointAddress {
		unsigned     Number       : 4;  // @0
		unsigned     _reserved4_6 : 3;  // @4
		UsbDirection Direction    : 1;  // @7
	}
UedEndpointAddress;

typedef
	enum UedAttributesSynchronisation {
		NoSynchronisation = 0,
		Asynchronous      = 1,
		Adaptive          = 2,
		Synchrouns        = 3,
	}
UedAttributesSynchronisation;

typedef
	enum UedAttributesUseage {
		Data                = 0,
		Feeback             = 1,
		ImplicitFeebackData = 2,
	}
UedAttributesUseage;

typedef
	struct UedAttributes {
		UsbTransfer                  Type            : 2;  // @0
		UedAttributesSynchronisation Synchronisation : 2;  // @2
		UedAttributesUseage          Usage           : 2;  // @4
		unsigned                     _reserved6_7    : 2;  // @6
	}
UedAttributes;

typedef
	enum UedPacketTransactions {
		None   = 0,
		Extra1 = 1,
		Extra2 = 2,
	}
UedPacketTransactions;

typedef
	struct UedPacket {
		unsigned              MaxSize        : 11;  // @0
		UedPacketTransactions Transactions   : 2;   // @11
		unsigned              _reserved13_15 : 3;   // @13
	}
UedPacket;

typedef
	struct UsbEndpointDescriptor {
		u8                 DescriptorLength;    // +0x0
		DescriptorTYPE     DescriptorType : 8;  // +0x1
		UedEndpointAddress EndpointAddress;     // +0x2
		UedAttributes      Attributes;          // +0x3
		UedPacket          Packet;              // +0x4
		u8                 Interval;            // +0x6
	} STRUCTPACK
UsbEndpointDescriptor;

//------------------------------------------------------------------------------
// USB device: String descriptor
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 9.6.7
//
typedef
	struct UsbStringDescriptor {
		u8             DescriptorLength;    // +0x0
		DescriptorTYPE DescriptorType : 8;  // +0x1
		u16            Data[];              // +0x2 amount varies
	} STRUCTPACK
UsbStringDescriptor;

#endif // _USBD_DESCRIPTORS_H
